package IC.asm.operands;

import IC.asm.Visitor;
import IC.asm.operands.MachineReg.Regs;

public class VirtualReg extends RegOperand {
	private static int 		Top = 0;
	private static int 		Base = 0;
	private int 			count;
	private Operand			binding=null;


	/**
	 * create a new register
	 */
	public VirtualReg() {
		this.count = Top++;
	}
	
	
	/**
	 * bind to real register
	 */
	public void bind() {
		this.binding = new MemOperand(new MachineReg(Regs.ebp), -12-4*count);
	}
	
	/** 
	 * get register binding
	 */
	public Operand getBinding() {
		return this.binding;
	}
	
	/**
	 * reset the general counter to 0
	 */
	public static void resetCounter() {
		Top = Base;
	}
	
	/**
	 * create with a static number
	 * @param num
	 */
	private VirtualReg(int num)
	{
		count = num;
	}
	
	/**
	 * allocates register
	 * @return
	 */
	public static VirtualReg Alloc() {
		assert (Base == Top);
		return new VirtualReg(Base++); 
	}
	
	/**
	 * deallocates latest register
	 */
	public static void Free(int count) {
		assert(Base +count >= 0);
		Base -= count;
	}
	
	/**
	 * @return the register index
	 */
	public int getNum() {
		return count;
	}

	/**
	 * @return the static register counter
	 */
	public static int getAllCount() {
		return Top;
	}

	@Override
	public <D, U> U accept(Visitor<D, U> v, D d) {
		return v.visit(this, d);
	}

	@Override
	public boolean equals(Object o)
	{
		if (! (o instanceof VirtualReg) )
			return false;
		return count == ((VirtualReg)o).count;
	}
}
